﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tracy.BasicServices;
using Tracy.DataModel;
using Tracy.Handlers;
using Tracy.DataAccess;
using Tracy.DataModel.UltraExplorer;
using SharedLib.DataAccess;
using SharedLib.XmlDataModel;
using Tracy.DataAccess.UltraExplorer;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Configuration;
using SharedLib.CrossCuttingFramework;
using SharedLib.WinFormMVCFramework;

namespace Tracy
{
    /// <summary>
    /// General Access to Tracy Services & Resources
    /// </summary>
    public class TracyFacade: AppFacade, IDisposable
    {
        #region Singleton
        /// <summary>
        /// Get the singleton instance
        /// </summary>
        public static TracyFacade Instance
        {
            get { return SingletonHelper._instance; }
        }

        /// <summary>
        /// Nested helper class
        /// </summary>
        private class SingletonHelper
        {
            static SingletonHelper() { }
            internal static readonly TracyFacade _instance = new TracyFacade();
        }
        private TracyFacade()
        {
            //Pre init codes come here
        }
        #endregion

        private FilterManager _filterManager = new FilterManager();

        public FilterManager FilterManager
        {
            get { return _filterManager; }
        }

        private TracyMessageDispatcher _messageDispatcher = new TracyMessageDispatcher();

        public TracyMessageDispatcher MessageDispatcher
        {
            get { return _messageDispatcher; }
        }

        private TracyPluginManager _pluginManager = new TracyPluginManager();

        public TracyPluginManager PluginManager
        {
            get { return _pluginManager; }
        }

        public IDataModelWithIDProvider<T> GetDataProvider<T>() where T : XmlDataModelWithAttributesAndID, new()
        {
            if (typeof(T) == typeof(Entry))
                return (IDataModelWithIDProvider<T>)EntryProvider;
            else if (typeof(T) == typeof(Resource))
                return (IDataModelWithIDProvider<T>)ResourceProvider;
            else if (typeof(T) == typeof(MediaFile))
                return (IDataModelWithIDProvider<T>)MediaFileProvider;

            return null;
        }

        public IClassifierProvider<T> GetClassifierProvider<T>() where T : XmlDataModelWithAttributesAndID, new()
        {
            if (typeof(T) == typeof(Entry))
                return (IClassifierProvider<T>)EntryClassifierProvider;
            //else if (typeof(T) == typeof(MediaFile))
            //    return (IClassifierProvider<T>)FileClassifierProvider;

            return null;
        }

        private EntryProvider _entryProvider = new EntryProvider();

        public EntryProvider EntryProvider
        {
            get { return _entryProvider; }
        }

        

        private ResourceProvider _resourceProvider = new ResourceProvider();

        public ResourceProvider ResourceProvider
        {
            get { return _resourceProvider; }
        }

        private MediaFileProvider _mediaFileProvider = new MediaFileProvider();

        public MediaFileProvider MediaFileProvider
        {
            get { return _mediaFileProvider; }
        }

        private TaskScheduler _taskScheduler = new TaskScheduler();

        public TaskScheduler TaskScheduler
        {
            get { return _taskScheduler; }
        }

        private DownloadManager _downloadManager = new DownloadManager();

        public DownloadManager DownloadManager
        {
            get { return _downloadManager; }
        }

        SearchEngine _searchEngine = new SearchEngine();

        public SearchEngine SearchEngine
        {
            get { return _searchEngine; }
        }

        private TagManager _tagManager = new TagManager();
        public TagManager TagManager
        {
            get { return _tagManager; }
        }

        private UserPreferencesManager _userPreferencesManager = new UserPreferencesManager();
        public UserPreferencesManager UserPreferencesManager
        {
            get { return _userPreferencesManager; }
        }

        private TracyConfigurationManager _tracyConfigurationManager = new TracyConfigurationManager();
        public TracyConfigurationManager ConfigurationManager
        {
            get { return _tracyConfigurationManager; }
        }

        EntryClassifierProvider _entryClassifierProvider = new EntryClassifierProvider();

        public EntryClassifierProvider EntryClassifierProvider
        {
            get { return _entryClassifierProvider; }
        }

        LanguageManager _languageManager = new LanguageManager("Languages");

        public LanguageManager LanguageManager
        {
            get { return _languageManager; }
        }


        public override void Initialize()
        {
            base.Initialize();

            //Init codes come here

            InitMessageDispatcher();

            InitPlugins();

            TaskScheduler.LoadSettings(null);

            InitDataProviders();

            DownloadManager.LoadSettings();

            LanguageManager.LoadSettings();
            string currentLanguage = System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
            if (LanguageManager.SupportedLanguages.Contains(currentLanguage)) LanguageManager.CurrentLanguage = currentLanguage;
            else LanguageManager.CurrentLanguage = "en-US";
            
        }

        private void InitDataProviders()
        {
            EntryProvider.LoadItems();
            ResourceProvider.LoadItems();
            MediaFileProvider.LoadItems();
        }

        private void InitMessageDispatcher()
        {
            MessageDispatcher.SetHandlerCapacity(typeof(FeedScanHandler).Name, 1); //must process one by one
            MessageDispatcher.SetHandlerCapacity(typeof(FileMonitorHandler).Name, 1); //must process one by one
            MessageDispatcher.SetHandlerCapacity(typeof(CopyFileHandler).Name, 1);//must process one by one

            MessageDispatcher.SetHandlerCapacity("GetDataFromURLHandler_KTXP", 5); //More threads for KTXP HTML reading
            
            //MessageDispatcher.SetHandlerCapacity("GetXmlFromURLHandler_KTXP", 5); //More threads for KTXP RSS reading
            //MessageDispatcher.SetHandlerCapacity("GetDataFromURLHandler_VeryCD", 5); //More threads for VeryCD HTML reading
            //MessageDispatcher.SetHandlerCapacity("GetDataFromURLHandler_VeryCD_FilePage", 10); //More threads for VeryCD RSS reading
        }

        private void InitPlugins()
        {
            PluginManager.LoadPlugins();
            LoadPluginsToDIContainer(PluginManager);
        }

        public void Dispose()
        {
            TaskScheduler.StopTimer();
            MessageDispatcher.Stop();
        }
    }
}
